import json
from channels.generic.websocket import WebsocketConsumer
from asgiref.sync import async_to_sync
from account_sys.models import User
from chat_sys.models import *


def datetime2str(trans_time):
    return trans_time.strftime("%Y.%m.%d %H:%M:%S")


def userId2UserInstance(user_id):
    if User.objects.filter(id=user_id).exists():
        return User.objects.get(id=user_id)
    else:
        return None


class ChatConsumer(WebsocketConsumer):

    def __init__(self, *args, **kwargs):
        super().__init__(args, kwargs)
        self.my_group_id = None
        self.user_id = None

    def connect(self):
        print('connect')
        print(self.channel_name)
        self.user_id = self.scope["url_route"]["kwargs"]["user_id"]
        # print(self.my_group_id)
        # 加入自己的个人频道
        private_group_name = 'private_' + self.user_id
        print("join " + private_group_name)
        async_to_sync(self.channel_layer.group_add)(private_group_name, self.channel_name)
        self.accept()

    def disconnect(self, close_code):
        # Leave room group
        message = self.channel_name + ' disconnect to websocket'
        group_name = 'private_' + self.user_id
        print(message)
        async_to_sync(self.channel_layer.group_discard)(
            group_name, self.channel_name
        )
        """    
        for group in self.my_group_id:
            group_name = 'chat_' + str(group)
            async_to_sync(self.channel_layer.group_send)(
                group_name, {"type": "chat.message", "code": 888, "message": message}
            )
            async_to_sync(self.channel_layer.group_discard)(
                group_name, self.channel_name
            )
        """
        pass

    # Receive message from WebSocket
    def receive(self, text_data):  # 后端消费者接收消息,前端发送
        print("I receive")
        print(text_data)
        text_data_json = json.loads(text_data)
        # print(text_data_json)
        msg_type = text_data_json["msg_type"]
        msg = text_data_json["msg"]
        user_id = text_data_json["sender_id"]
        # 发送者实例
        sender_instance = userId2UserInstance(user_id)
        # 接收者实例
        receiver_id = text_data_json["receiver_id"]
        receiver_instance = userId2UserInstance(receiver_id)

        if 'file' not in text_data_json:
            message_instance = Message.objects.create(
                msg_type=msg_type,
                sender=sender_instance,
                receiver=receiver_instance,
                content=msg,
                send_time=get_now_time()
            )
        else:

            file = text_data_json['file']
            message_instance = Message.objects.create(
                sender=sender_instance,
                receiver=receiver_instance,
                content=msg,
                file=file,
                msg_type="file",
                send_time=get_now_time()
            )
        msg_id = message_instance.id
        # 向前端发送自己发送的消息(自己发送的消息也要显示在页面上),未加入其频道也可向其发送,且自身不会收到自己的消息，
        # 不触发chat_message()
        # 故调用self.send向前端发送
        self.send(text_data=json.dumps(message_instance.parse_dict()))
        # 向私聊对象的个人组发送消息
        target_group_name = 'private_' + str(receiver_id)
        async_to_sync(self.channel_layer.group_send)(
            target_group_name,
            message_instance.parse_dict()
        )

    # Receive message from room group
    # 从频道接受消息并发送到前端自己接受到的消息
    def chat_message(self, event):
        sender_id = event["sender_id"]
        msg_id = event["msg_id"]
        msg_type = event["msg_type"]
        msg = event["content"]
        send_time = event["send_time"]
        if event.get("file") is not None:
            file = event["file"]
        else:
            file = ''
        # Send message to WebSocket
        print('send2front')
        receiver_id = event["receiver_id"]
        print('send2User:')
        print(receiver_id)
        self.send(text_data=json.dumps({
            "msg_id": msg_id,
            "msg_type": msg_type,
            "sender_id": sender_id,
            "receiver_id": receiver_id,
            "content": msg,
            "send_time": send_time,
            'file': file
        }))
